package developer.笔试题.猜数字;

import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * @author zhangyongkang
 * @time 2025/7/18 16:46
 * @description
 */
public class GuessNum {
    public static void main(String[] args) {
        Block block = new Block();

        new Thread(new Guess(block)).start();
        new Thread(new Producer(block)).start();
    }

    static class Block {
        public int status = 0;
        public boolean isFirst = true;
        public boolean isGuessFirst = true;
        public int guessNum = 0;
        public int trueVal;
    }

    static class Guess implements Runnable {
        private final Block block;

        public Guess(Block block) {
            this.block = block;
        }

        @Override
        public void run() {
            while (true) {
                synchronized (block) {
                    if (block.isFirst) {
                        try {
                            System.out.println("猜数者要进入睡眠了");
                            block.wait();//释放锁
                            block.notifyAll();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                    if (block.isGuessFirst) {
                        block.isGuessFirst = false;
                        block.guessNum = new Random().nextInt(1000);
                    }

                    System.out.println("真实的值是:" + block.trueVal + ",猜的值是" + block.guessNum);
                    try {
                        TimeUnit.MILLISECONDS.sleep(100);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    switch (block.status) {
                        case 1://小了
                            System.out.println("小了");
                            block.guessNum++;
                            break;
                        case 2://大了
                            System.out.println("大了");
                            block.guessNum--;
                            break;
                    }
                    if (block.status == 3) {
                        System.out.println(block.guessNum);
                        break;
                    }
                    block.notifyAll();//通知猜的线程醒来
                    try {
                        block.wait();//释放锁
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
            System.out.println(block.guessNum+"结束");

        }
    }

    static class Producer implements Runnable {
        private final Block block;

        public Producer(Block block) {
            this.block = block;
        }

        @Override
        public void run() {
            while (true) {
                synchronized (block) {
                    if (block.isFirst) {
                        //生成随机数
                        block.trueVal = new Random().nextInt(1000);
                        System.out.println("生成随机数" + block.trueVal);
                        block.isFirst = false;
                        try {
                            block.notifyAll();//通知猜的线程醒来
                            block.wait();//释放锁
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }

                    }
                    int guessNum = block.guessNum;
                    int trueVal = block.trueVal;
                    if (guessNum == trueVal) {
                        block.notifyAll();//通知猜的线程醒来
                        block.status = 3;
                        break;
                    } else {
                        block.status = guessNum > trueVal ? 2 : 1;
                    }


                    block.notifyAll();//通知猜的线程醒来
                    try {
                        block.wait();//释放锁
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }

                }
            }
        }
    }
}
